<?php
/**
 * 《网络流量》实现类
 *
 * @author 孙晓晔
 * @version $Id: Network.class.php 1035 2010-03-26 05:24:59Z sunxy $
 */

require_once(dirname(__FILE__) . '/LogUtil.class.php');

class Network extends LogUtil {
	public $tbl = Constant::tbl_network_flow;
	public $tbl_dd = Constant::tbl_network_flow_daily;

	public $fx = array(
        '-' => '请选择',
        '1' => '上传',
        '2' => '下载',
	);

	public $orderby = array(
        '-' => '请选择',
        'pkts' => '数据包',
		'bytes' => '流量',
        'ip' => 'IP',
	);

	public $groupby = array(
		'-' => '请选择',
		'fx' => '类型',
		'ip' => 'IP',
		'2' => '日期',
		'3' => '月份',
	);

	function __construct() {
		$request['update'] = '$Date: 2009/03/06 11:29:07 $';
		$request['revision'] = '$Revision: 1.2 $';

		parent::__construct($request);
	}

	function pretreat($controller) {
		parent::pretreat($controller);

		$controller->assign_by_ref('fx_option', $this->fx);
	}

	/**
	 * 首页
	 *
	 * @param Controller $controller
	 * @param array $request
	 */
	function layout($controller, $request) {

		$controller->display($request, 'log/action');
		return true;
	}

	/**
	 *
	 *
	 * @param Controller $controller
	 * @param array $request
	 */
	function find($controller, $request) {
		$this->pretreat($controller);
			
		// $controller->assign('t1', strtotime('-1 day'));
		// $controller->assign('t2', strtotime('+1 day'));
		
		$controller->assign('orderby_s', 'bytes');

		$controller->display($request, 'log/network/find');
		return true;
	}

	function _orderby_x($controller, $row, $px) {
		$orderby = $this->orderby['1'];
		$row['orderby_x'] = $row['createtime'];

		if (empty($px) || $px == '-' || $px == '1') {
			$controller->assign('orderby', $orderby);

			return $row;
		}

		if ($px == '2') {
			$orderby = $this->orderby[$px];
			$row['orderby_x'] = $row['modifytime'];
		}

		$controller->assign('orderby', $orderby);

		return $row;
	}

	function _where($request) {
		$dd_s = $request['dd_s'];
		$fx_s = $request['fx_s'];
		$ip_s = $request['ip_s'];

		$where = " WHERE 1=1";
		if (!empty($dd_s)) {
			$where .= " AND dd = '" . $dd_s . "'";
		}

		if (!empty($fx_s) && $fx_s <> '-') {
			$where .= " AND fx = '" . $fx_s . "'";
		}

		if (!empty($ip_s)) {
			$where .= " AND ip like '" . $ip_s . "%'";
		}

		$where .= $this->_where_default($request);
		$where = $this->_where_aa($where);

		return $where;
	}

	/**
	 *
	 *
	 * @param Controller $controller
	 * @param array $request
	 */
	function findPost($controller, $request) {
		$this->pretreat($controller);

		$this->findPara($controller, $request);

		$dd_s = $request['dd_s'];

		if (!empty($dd_s)) {
			$this->tbl = $this->tbl_dd;
		}

		$db = newdb($this->dsn_r);
		$fmt = "SELECT * FROM %s a %s %s";
		$where = $this->_where($request);
		$orderby = $this->_orderby();
		$sql = sprintf($fmt, $this->tbl, $where, $orderby);
		debug($sql);

		$pager_option = array (
            'db' => $db,
            'sql' => $sql,
            'PageSize' => $this->pagesize,
            'CurrentPageID' => $request['p'],
            'numItems' => $request['n']
		);

		$pager = @new Pager($pager_option);
		$data = $pager->getPageData();

		$total = 0;
		if ($pager->number > 0) {
			$count = 0;
			$from = $pager->from;
			while ($count < $pager->number) {
				$row = $data[$count];
				$row = $this->_view(null, $row);

				// $total += $row['bytes'];
				
				$row = $this->_orderby_x($controller, $row, $this->orderby_s);
				$data[$count] = $row;
				$count++;
			}
			$controller->assign_by_ref('result', $data);
			$controller->assign_by_ref('pager', $pager);
		}
		
		// $controller->assign_by_ref('total_t', printsize($total));

		if (!empty($dd_s)) {
			$controller->display($request, 'log/network/list_dd');
		} else {
			$controller->display($request, 'log/network/list');
		}
		return true;
	}
	
	function _view($id = 0, $row = null) {
		if ($row == null) {
			clean($this->tbl . "_id_" . $id);
			$row = $this->id($this->tbl, $id);
		}
		
		$row['fx_t'] = $this->fx[$row['fx']];
		// $row['bytes_t'] = printsize($row['bytes']);
		$row['speed'] = number_format($row['bytes'] / 300, 2, '.', '');
		
		$row['mac_x'] = $this->_emp_mac($row['ip']);

		$row = $this->_view_t($row);

		return $row;
	}

	/**
	 *
	 *
	 * @param Controller $controller
	 * @param array $request
	 */
	function group($controller, $request) {
		$this->pretreat($controller);

		// $controller->assign('t1', strtotime('-7 day'));
		// $controller->assign('t2', strtotime('+1 day'));

		$controller->display($request, 'log/network/group');
		return true;
	}

	function groupby($controller, $px) {
		$px = $this->groupby_aa($px, $this->groupby, 'fx');

		$controller->assign('groupby', $this->groupby[$px]);

		return $this->groupby_dd($px);
	}
	
	function groupby_dd($px) {
		if ($px == '1') {
			return "DATE_FORMAT(date, '%Y-%m-%d %H')";
		}

		if ($px == '2') {
			return "DATE_FORMAT(date, '%Y-%m-%d')";
		}

		if ($px == '3') {
			return "DATE_FORMAT(date, '%Y-%m')";
		}

		return $px;
	}

	function groupPost($controller, $request) {
		$this->pretreat($controller);
			
		$this->groupPara($controller, $request);
		
		$this->tbl = $this->tbl_dd;

		$fmt = "SELECT %s AS a, SUM(bytes) AS c FROM %s a ";
		$sql = sprintf($fmt, $this->s, $this->tbl);

		$where = $this->_where($request);

		$request['sql'] = sprintf("%s %s GROUP BY %s ORDER BY %s %s", $sql, $where, $this->s, $this->orderby, $this->desc);

		$this->_group($controller, $request);

		// $controller->display($request, 'list');
		return true;
	}

	function _name($row, $px) {
		if (empty($px) || $px == '-' || $px == 'fx') {
			$row['a'] = $this->fx[$row['a']];
		} elseif ($px == 'ip') {
			$row['mac_x'] = $this->_emp_mac($row['a']);			
			$row['a'] = sprintf("%s[%s]", $row['mac_x']['emp_t'], $row['a']);
		} else {
		
			$row = $this->_name_t($row, $px);
		}

		return $row;
	}

	function ns($controller, $request) {
		$this->pretreat($controller);

		$this->_migrate();
		
		$db = newdb($this->dsn_w);
		$fmt = "TRUNCATE TABLE %s";
		$sql = sprintf($fmt, $this->tbl);
		// echo $sql . "\n";
		$db->query($sql);

		$this->z_in("jr-input");
		$this->z_out("jr-output");

		$cmd = "/sbin/iptables -Z";
		$ret = shell_exec($cmd);
		
		$request['a'] = '340';
		$request['title'] = '网络监测（南山）';
		$this->_tj_b($controller, $request);

		logdate($controller, $request);
		return true;
	}
	
	function qx($controller, $request) {
		$this->pretreat($controller);
	
		$this->_migrate();
	
		$db = newdb($this->dsn_w);
		$fmt = "TRUNCATE TABLE %s";
		$sql = sprintf($fmt, $this->tbl);
		// echo $sql . "\n";
		$db->query($sql);
	
		$this->z_in("jr-input");
		$this->z_out("jr-output");
	
		$cmd = "/sbin/iptables -Z";
		$ret = shell_exec($cmd);
	
		$request['a'] = '179';
		$request['title'] = '网络监测（清溪）';
		$this->_tj_b($controller, $request);
	
		logdate($controller, $request);
		return true;
	}

	function sj($controller, $request) {
		$this->pretreat($controller);

		$this->_migrate();
		
		$db = newdb($this->dsn_w);
		$fmt = "TRUNCATE TABLE %s";
		$sql = sprintf($fmt, $this->tbl);
		// echo $sql . "\n";
		$db->query($sql);

		$this->z_in("jr-input");
		$this->z_out("jr-output");

		$cmd = "/sbin/iptables -Z";
		$ret = shell_exec($cmd);
		
		$request['a'] = '341';
		$request['title'] = '网络监测（沙井）';
		$this->_tj_b($controller, $request);

		logdate($controller, $request);
		return true;
	}
	
	function _migrate() {
		$db = newdb($this->dsn_w);
		$fmt = "SELECT * FROM %s";
		$sql = sprintf($fmt, $this->tbl);
		echo $sql . "\n";
		$result = $db->query($sql);
		while ($row = $db->fetch_array($result)) {
			$this->_migrate_row($row);
			echo ".";
		}
	}
	
	function _migrate_row($row) {
		$dd = date('Y-m-d');
		$db = newdb($this->dsn_w);
		$fmt = "SELECT * FROM %s WHERE dd = '%s' AND fx = '%s' AND ip = '%s'";
		$sql = sprintf($fmt, $this->tbl_dd, $dd, $row['fx'], $row['ip']);
		// echo $sql . "\n";
		$result = $db->query($sql);
		if ($db->num_rows($result) > 0) {
			$fmt = "UPDATE %s SET pkts = pkts + %s, bytes = bytes + %s WHERE dd = '%s' AND fx = '%s' AND ip = '%s'";
		} else {
			$fmt = "INSERT INTO %s(pkts, bytes, dd, fx, ip, createtime) VALUES('%s', '%s', '%s', '%s', '%s', now())";
		}
		$sql = sprintf($fmt, $this->tbl_dd, $row['pkts'], $row['bytes'], $dd, $row['fx'], $row['ip']);
		// echo $sql . "\n";
		$db->query($sql);
	}
	
	function _tj_b($controller, $request) {
		$bb = $this->_list_email($request['a']);
		// print_r($bb);
		if (!$bb || count($bb) == 0) {
			return false;
		}
		
		$from = $this->email;
		$subject = $request['title'];
		
		$list = $this->_tj();
		if (!$list || count($list) == 0) {
			return false;
		}
		
		$controller->assign_by_ref('list', $list);
					
		$body = $this->_tj_html($controller, $request, 'log/network/tj_b');
		
		$this->_tj_mail($from, $bb, $subject, $body);
	}
	
	function _tj() {
		$kb = 1024;
		$mb = 1024 * $kb;
		
		require_once(dirname(__FILE__) . '/../emp/Mac.class.php');
		$aa = new Mac();
	
		$db = newdb($this->dsn_w);
		$fmt = "SELECT * FROM %s";		
		$sql = sprintf($fmt, $this->tbl);
		echo $sql . "\n";
		$result = $db->query($sql);
		$data = array();
		while ($row = $db->fetch_array($result)) {
			if ($aa->alarm($row['ip'], $row['fx'], $row['bytes'])) {
				continue;
			}
			
			$row = $this->_view(null, $row);
		
			$data[] = $row;
		}
		
		return $data;
	}
	
	

	/*
	 * 下载
	 */
	function z_in($rule) {
		$cmd = sprintf("/sbin/iptables -L %s -n -vx", $rule);
		echo $cmd . "\n";
		$ret = shell_exec($cmd);
		// echo $ret;

		$aa = preg_split("/[\\n]+/i", $ret);
		// print_r($a);

		$db = newdb($this->dsn_w);
		while (list($k, $v) = each($aa)) {
			$buf = trim($v);
			if (strlen($buf) < 10) {
				continue;
			}

			if (!preg_match("/^(\d+)/i", $buf)) {
				echo $buf . "\n";
				continue;
			}

			$a = preg_split("/[\t|\s]+/i", $buf);
			// print_r($a);
			if ($a[0] == 0 || count($a) <> 9) {
				continue;
			}

			echo $buf . "\n";
			$pkts = $a[0];
			$bytes = $a[1];
			$ip = $a[8];

			$fmt = "INSERT INTO %s(fx, pkts, bytes, ip, createtime) VALUES('2', '%s', '%s', '%s', now())";
			$sql = sprintf($fmt, $this->tbl, $pkts, $bytes, $ip);
			echo $sql . "\n";
			$db->query($sql);

			echo ".";
		}
	}

	/*
	 * 上传
	 */
	function z_out($rule) {
		$cmd = sprintf("/sbin/iptables -L %s -n -vx", $rule);
		echo $cmd . "\n";
		$ret = shell_exec($cmd);
		// echo $ret;

		$aa = preg_split("/[\\n]+/i", $ret);
		// print_r($a);

		$db = newdb($this->dsn_w);
		while (list($k, $v) = each($aa)) {
			$buf = trim($v);
			if (strlen($buf) < 10) {
				continue;
			}

			if (!preg_match("/^(\d+)/i", $buf)) {
				echo $buf . "\n";
				continue;
			}

			$a = preg_split("/[\t|\s]+/i", $buf);
			// print_r($a);
			if ($a[0] == 0 || count($a) <> 9) {
				continue;
			}

			echo $buf . "\n";

			$pkts = $a[0];
			$bytes = $a[1];
			$ip = $a[7];

			$fmt = "INSERT INTO %s(fx, pkts, bytes, ip, createtime) VALUES('1', '%s', '%s', '%s', now())";
			$sql = sprintf($fmt, $this->tbl, $pkts, $bytes, $ip);
			echo $sql . "\n";
			$db->query($sql);

			echo ".";
		}
	}
	
	function _emp_mac($ip) {
		require_once(dirname(__FILE__) . '/../emp/Mac.class.php');
		$aa = new Mac();
		
		return $aa->_view_ip($ip);
	}

	function qq($controller, $request) {

		$file = "/home/ftp/tecmold.com/mac.txt";
		$file = "d:/qq.txt";
		$fd = fopen($file, "r");
		while (!feof($fd)) {
			$buf = trim(fgets($fd));
			// echo $buf;

			if (strlen($buf) < 5 || preg_match("/^#/i", $buf)) {
				continue;
			}

			$mac = $a[2];
			$ip = $a[0];

			$fmt = "/sbin/iptables -A qq-output -d %s/24 -j DROP\n";
			$s = sprintf($fmt, trim($buf));
			echo $s;
		}
		fclose($fd);

		echo "\n" . $_REQUEST['do'] . "\n";

		logdate($controller, $request);
		return true;
	}

	function t($controller, $request) {
		$qq = array();
		$file = "d:/qq.txt";
		$fd = fopen($file, "r");
		while (!feof($fd)) {
			$buf = trim(fgets($fd));
			// echo $buf;

			if (strlen($buf) < 5 || preg_match("/^#/i", $buf)) {
				continue;
			}
			$qq[] = trim($buf . '/24');
		}
		fclose($fd);

		require_once APP_LIB . 'IpAddr.class.php';

		$ipaddr = new IpAddr();

		$file = "/home/ftp/tecmold.com/mac.txt";
		$file = "d:/ketty.txt";
		$fd = fopen($file, "r");
		while (!feof($fd)) {
			$buf = trim(fgets($fd));
			// echo $buf;

			if (strlen($buf) < 5 || preg_match("/^#/i", $buf)) {
				continue;
			}

			$a = parse_url($buf);

			// print_r($a);
			$host = $a['host'];
			$ip = gethostbyname($host);
			$fmt = "%s %s\n";
			$s = sprintf($fmt, $host, $ip);

			if ($this->ip($ipaddr, $qq, $ip)) {
				echo $s;
			}
		}
		fclose($fd);

		echo "\n" . $_REQUEST['do'] . "\n";

		logdate($controller, $request);
		return true;
	}

	function ping($controller, $request) {

		for ($i = 1; $i < 255; $i++) {
			$fmt = "/bin/ping 192.168.2.%s -c 3";
			$cmd = sprintf($fmt, $i);
			// shell_exec($cmd);

			$fmt = "/bin/ping 192.168.3.%s -c 3";
			$cmd = sprintf($fmt, $i);
			echo shell_exec($cmd);
		}

		echo "\n" . $_REQUEST['do'] . "\n";

		logdate($controller, $request);
		return true;
	}

	function ip($ipaddr, $qq, $ip) {
		reset($qq);
		while (list($k, $v) = each($qq)) {
			if ($ipaddr->contains($v, $ip)) {
				$fmt = "%s %s\n";
				echo sprintf($fmt, $v, $ip);
				return true;
			}
		}

		return false;
	}

	/*
	 * 上传
	 */
	function _tj_a($controller, $request) {
		$this->tbl = $this->tbl_dd;

		$fx = $request['fx'];

		$groupby_s = 'ip';
		$s = $this->groupby($controller, $groupby_s);
		$df = "DATE_FORMAT(DATE_ADD(now(), INTERVAL -1 DAY), '%Y-%m-%d')";

		$db = newdb($this->dsn_r);
		$sql = "SELECT $s AS a, SUM(bytes) AS c FROM " . $this->tbl . " a ";
		$where = " WHERE fx = " . $fx . " AND dd = " . $df;

		$orderby = ' ORDER BY c DESC';

		$groupby = " GROUP BY $s";
		$sql .= $where . $groupby . $orderby;
		debug($sql);
		$result = $db->query($sql);

		$data = array();
		$count = 0;
		$xx = 0;
		$total = 0;
		while ($row = $db->fetch_array($result)) {
			$total += $row['c'];
			if ($count > 100) {
				$xx += $row['c'];
				continue;
			}

			$row = $this->_name($row, $groupby_s);
			$data[] = $row;
			$count++;
		}

		if ($xx > 0) {
			$data[] = array('a'=>'其它', 'c'=>$xx);
		}

		$aa = array();
		while (list($k, $v) = each($data)) {
			$v['p'] = number_format(($v['c'] / $total) * 100, 2, '.', '') . "%";
			$v['c'] = printsize($v['c']);

			$aa[] = $v;
		}
			
		$a = array();
		$c = array();
		reset($data);
		while (list($k, $v) = each($data)) {
			$a[] = $v['a'];
			$c[] = $v['c'];
		}
			
		$sa = join(",", $a);
		// echo "\n";
		$sc = join(",", $c);
			
		$sa = trim($sa, ",");
			
		$controller->assign('sa', $sa);
		$controller->assign('sc', $sc);

		$controller->assign_by_ref('total', printsize($total));

		$controller->assign_by_ref('result', $aa);

		return $controller->sunxy($request, 'log/network/tj_a');
	}
	
	function tj($controller, $request) {
		$bb = $this->_list_email('312');
		// print_r($bb);
		if (!$bb || count($bb) == 0) {
			return false;
		}
		
		$from = $this->email;
		$subject = '网络使用情况';
		
		$this->tbl = $this->tbl_dd;

		$aa = array(
			'上传情况'=>array('fx' => "1"),	
			'下载情况'=>array('fx' => "2"),
		);
		
		$this->_tj_bb($controller, $aa);

		$body = $this->_tj_html($controller, $request, 'log/network/tj_list');
		
		$this->_tj_mail($from, $bb, $subject, $body);

		logdate($controller, $request);
		return true;
	}
	
	function _tj2($v) {
		$this->result_s = 50;
		$this->groupby_s = 'ip';
			
		$s = $this->groupby_s;
		$df = "DATE_FORMAT(DATE_ADD(now(), INTERVAL -1 DAY), '%Y-%m-%d')";
		
		$fmt = "SELECT %s AS a, SUM(bytes) AS c FROM %s a WHERE fx = '%s' AND dd = %s GROUP BY %s ORDER BY c DESC";
		$sql = sprintf($fmt, $s, $this->tbl, $v['fx'], $df, $s);
				
		echo $sql . "\n";

		return $this->_group_tj3($sql);
	}
	
	function _group_tj3($sql) {
		$db = newdb($this->dsn_r);
		$result = $db->query($sql);

		$groupby_s = 'ip';
		
		$data = array();
		$count = 0;
		$xx = 0;
		$total = 0;
		while ($row = $db->fetch_array($result)) {
			$total += $row['c'];
			if ($count > 100) {
				$xx += $row['c'];
				continue;
			}

			$row = $this->_name($row, $groupby_s);
			$data[] = $row;
			$count++;
		}

		if ($xx > 0) {
			$data[] = array('a'=>'其它', 'c'=>$xx);
		}

		$aa = array();
		while (list($k, $v) = each($data)) {
			$v['p'] = number_format(($v['c'] / $total) * 100, 2, '.', '') . "%";
			$v['c'] = printsize($v['c']);

			$aa[] = $v;
		}

		$ret['data'] = $aa;
		$ret['total'] = printsize($total);
		
		return $ret;
	}
}
?>
